package com.ruoyi.learn.java.collection;

import java.util.*;

public class LinkedHashMapDemo {
    public static void main(String[] args) {
        System.out.println("=== LinkedHashMap 全场景演示 ===\n");

        // 🌟 场景 1：默认行为 - 按插入顺序排序
        demoInsertionOrder();

        // 🌟 场景 2：按访问顺序排序（accessOrder = true）
        demoAccessOrder();

        // 🌟 场景 3：实现 LRU 缓存（自动淘汰最老元素）
        demoLRUCache();

        // 🌟 场景 4：与 HashMap 遍历顺序对比
        compareWithHashMap();
    }

    // ✅ 场景 1：插入顺序演示
    static void demoInsertionOrder() {
        System.out.println("1. LinkedHashMap - 插入顺序演示");
        LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
        map.put("Apple", 1);
        map.put("Banana", 2);
        map.put("Cherry", 3);
        map.put("Date", 4);

        System.out.println("插入后遍历:");
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println("  " + entry.getKey() + " -> " + entry.getValue());
        }
        // 输出顺序：Apple, Banana, Cherry, Date（保证插入顺序）
        System.out.println();
    }

    // ✅ 场景 2：访问顺序演示（accessOrder = true）
    static void demoAccessOrder() {
        System.out.println("2. LinkedHashMap - 访问顺序演示 (accessOrder = true)");
        LinkedHashMap<String, String> map = new LinkedHashMap<>(16, 0.75f, true); // 第三个参数：accessOrder

        map.put("A", "First");
        map.put("B", "Second");
        map.put("C", "Third");

        System.out.println("初始顺序: " + map.keySet()); // [A, B, C]

        // 访问 A 和 B
        map.get("A");
        map.get("B");

        System.out.println("访问 A 和 B 后顺序: " + map.keySet());
        // 输出: [C, A, B] → C 最老，A/B 因被访问变为“新”的
        System.out.println();
    }

    // ✅ 场景 3：LRU 缓存实现
    static void demoLRUCache() {
        System.out.println("3. LRU 缓存实现（容量为 3）");

        LinkedHashMap<String, String> lruMap = new LinkedHashMap<String, String>(16, 0.75f, true) {
            // 当元素超过 3 个时，自动删除最老的
            @Override
            protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
                return size() > 3;
            }
        };

        lruMap.put("1", "Page 1");
        lruMap.put("2", "Page 2");
        lruMap.put("3", "Page 3");
        System.out.println("插入 3 个后: " + lruMap.keySet());

        // 访问 Page 1
        lruMap.get("1");
        System.out.println("访问 Page 1 后: " + lruMap.keySet());

        // 插入 Page 4 → 应该淘汰 Page 2（最老未访问）
        lruMap.put("4", "Page 4");
        System.out.println("插入 Page 4 后（淘汰 Page 2）: " + lruMap.keySet());

        // 再访问 Page 3
        lruMap.get("3");
        lruMap.put("5", "Page 5"); // 淘汰 Page 4
        System.out.println("插入 Page 5 后（淘汰 Page 4）: " + lruMap.keySet());
        System.out.println();
    }

    // ✅ 场景 4：与 HashMap 遍历顺序对比
    static void compareWithHashMap() {
        System.out.println("4. LinkedHashMap vs HashMap 遍历顺序对比");

        Map<String, Integer> hashMap = new HashMap<>();
        Map<String, Integer> linkedHashMap = new LinkedHashMap<>();

        // 插入相同数据
        String[] keys = {"Zebra", "Apple", "Mango", "Dog", "Cat"};
        for (int i = 0; i < keys.length; i++) {
            hashMap.put(keys[i], i);
            linkedHashMap.put(keys[i], i);
        }
        LinkedHashMap<String, String> lruMap = new LinkedHashMap<String, String>(16, 0.75f, true) {
            @Override
            protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
                return size() > 3;
            }
        };

        System.out.println("HashMap 遍历顺序（无序）: ");
        for (String key : hashMap.keySet()) {
            System.out.print(key + " ");
        }
        System.out.println("\n（每次运行可能不同）");

        System.out.println("LinkedHashMap 遍历顺序（插入顺序）: ");
        for (String key : linkedHashMap.keySet()) {
            System.out.print(key + " ");
        }
        System.out.println("（始终保证插入顺序）");
        System.out.println();
    }
}